package eu.vranckaert.workRegistrationWidget.service.impl;

import android.content.Context;
import android.location.Location;
import android.os.Environment;
import android.util.Log;
import com.google.inject.Inject;
import eu.vranckaert.workRegistrationWidget.R;
import eu.vranckaert.workRegistrationWidget.dao.TimeRegDao;
import eu.vranckaert.workRegistrationWidget.domain.TimeRegistration;
import eu.vranckaert.workRegistrationWidget.exceptions.EndDateBeforeStartDateException;
import eu.vranckaert.workRegistrationWidget.service.RegistrationService;
import eu.vranckaert.workRegistrationWidget.util.DateUtil;
import eu.vranckaert.workRegistrationWidget.util.Preferences;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author Dirk Vranckaert
 * Date: 23-apr-2010
 * Time: 19:06:48
 */
public class RegistrationServiceImpl implements RegistrationService {
    private static final String LOG_TAG = RegistrationServiceImpl.class.getName();
    private static final String EXPORT_EXTENSION = ".csv";
    private static final String GOOGLE_MAPS_URI = "http://maps.google.com/maps?ll=#LAT#,#LON#";

    @Inject
    TimeRegDao timeRegDao;

    public TimeRegistration createRegistrationForCurrentTime(Context context) throws EndDateBeforeStartDateException {
        Date currentTime = new Date();

        TimeRegistration timeRegistration = timeRegDao.findLatestRegistration(context);

        if (timeRegistration == null || timeRegistration.getEndDate() != null) {
            timeRegistration = new TimeRegistration();
            timeRegistration.setStartDate(currentTime);
            timeRegistration.setStartAction(true);
        } else if (timeRegistration.getStartDate() != null) {
            if (timeRegistration.getStartDate().compareTo(currentTime) < 0) {
                timeRegistration.setEndDate(currentTime);
                timeRegistration.setStartAction(false);
            } else {
                throw new EndDateBeforeStartDateException("The enddate is before the startdate!");
            }
        } else {
            timeRegistration.setStartDate(currentTime);
            timeRegistration.setStartAction(true);
        }

        return timeRegDao.saveOrUpdate(context, timeRegistration);
    }

    public List<TimeRegistration> getAllTimeRegistrations(Context context) {
        List<TimeRegistration> registrations = timeRegDao.findAll(context);

        return registrations;
    }

    @Override
    public TimeRegistration getLatestTimeRegistration(Context context) {
        return timeRegDao.findLatestRegistration(context);
    }

    @Override
    public void removeAllRegistrations(Context context) {
        timeRegDao.removeAll(context);
    }

    @Override
    public void removeRegistration(Context context, TimeRegistration timeRegistration) {
        timeRegDao.delete(context, timeRegistration);
    }

    @Override
    public void saveOrUpdateRegistration(Context context, TimeRegistration timeRegistration) {
        timeRegDao.saveOrUpdate(context, timeRegistration);
    }

    @Override
    public File export(Calendar startCal, Calendar endCal, String fileName, Context context) {
        File file = null;
        final String NOT_AVAILABLE = context.getString(R.string.notAvailable);
        List<TimeRegistration> registrations = getAllTimeRegistrations(context);
        String separator = Preferences.getExportFileCSVSeparator(context);

        FileWriter fwriter = null;
        BufferedWriter out = null;
        try {
            File defaultStorageDirectory = Environment.getExternalStorageDirectory();
            file = new File(defaultStorageDirectory.getAbsolutePath() + File.separator + fileName + EXPORT_EXTENSION);
            boolean fileAlreadyExists = file.createNewFile();
            fwriter = new FileWriter(file);
            out = new BufferedWriter(fwriter);
            out.write("Startdate" + separator + "Starttime" + separator + "Enddate" + separator + "Endtime" + separator
                    + "Duration" + separator + "Startlocation" + separator + "Endlocation\n");

            for(TimeRegistration timeReg : registrations) {
                String column1 = DateUtil.formatDate(timeReg.getStartDate(), context); //Startdate
                String column2 = DateUtil.formatTime(timeReg.getStartDate(), context); //Starttime
                String column3 = ""; //Enddate
                String column4 = ""; //Endtime
                String column5 = "0:00"; //Duration
                if(timeReg.getEndDate() != null && timeReg.getEndDate().getTime() > 0L) {
                    column3 = DateUtil.formatDate(timeReg.getEndDate(), context);
                    column4 = DateUtil.formatTime(timeReg.getEndDate(), context);
                    column5 = DateUtil.calculateDurationInTimeFormat(timeReg.getStartDate(), timeReg.getEndDate());
                }
                String column6 = NOT_AVAILABLE; //startLocation
                String column7 = NOT_AVAILABLE; //endLocation
                if (timeReg.getStartLatitude() != null && timeReg.getStartLongtitude() != null &&
                        timeReg.getStartLatitude() > 0 && timeReg.getStartLongtitude() > 0) {
                    column6 = GOOGLE_MAPS_URI;
                    column6 = column6.replace("#LON#", timeReg.getStartLongtitude().toString());
                    column6 = column6.replace("#LAT#", timeReg.getStartLatitude().toString());
                }
                if (timeReg.getEndLatitude() != null && timeReg.getEndLongtitude() != null &&
                        timeReg.getEndLatitude() > 0 && timeReg.getEndLongtitude() > 0) {
                    column7= GOOGLE_MAPS_URI;
                    column7 = column7.replace("#LON#", timeReg.getEndLongtitude().toString());
                    column7 = column7.replace("#LAT#", timeReg.getEndLatitude().toString());
                }
                Log.d(LOG_TAG, "Exported startlocation is " + column6);
                Log.d(LOG_TAG, "Exported endlocation is " + column7);

                out.write(
                        column1 + separator +
                        column2 + separator +
                        column3 + separator +
                        column4 + separator +
                        column5 + separator +
                        column6 + separator +
                        column7 + "\n"
                );
            }
            out.close();
            fwriter.close();
        } catch (IOException e) {
            Log.e(LOG_TAG, "Exception during export");
            e.printStackTrace();
            return null;
        }

        return file;
    }
}
